package com.crm.im.core.handler;

import static io.netty.handler.codec.http.HttpMethod.GET;
import static io.netty.handler.codec.http.HttpResponseStatus.BAD_REQUEST;
import static io.netty.handler.codec.http.HttpResponseStatus.FORBIDDEN;
import static io.netty.handler.codec.http.HttpResponseStatus.NOT_FOUND;
import static io.netty.handler.codec.http.HttpResponseStatus.OK;
import static io.netty.handler.codec.http.HttpVersion.HTTP_1_1;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.DefaultFullHttpResponse;
import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.FullHttpResponse;
import io.netty.handler.codec.http.HttpHeaders;
import io.netty.handler.codec.http.HttpRequest;
import io.netty.handler.ssl.SslHandler;
import io.netty.util.CharsetUtil;
  
  /**
41   * Outputs index page content.
42   */
  public class WebSocketIndexPageHandler extends SimpleChannelInboundHandler<FullHttpRequest> {
  
      private final String websocketPath;
  
      public WebSocketIndexPageHandler(String websocketPath) {
          this.websocketPath = websocketPath;
      }
  
      @Override
      protected void channelRead0(ChannelHandlerContext ctx, FullHttpRequest req) throws Exception {
          // Handle a bad request.
          if (!req.getDecoderResult().isSuccess()) {
              sendHttpResponse(ctx, req, new DefaultFullHttpResponse(HTTP_1_1, BAD_REQUEST));
              return;
          }
  
          // Allow only GET methods.
          if (req.getMethod() != GET) {
              sendHttpResponse(ctx, req, new DefaultFullHttpResponse(HTTP_1_1, FORBIDDEN));
              return;
          }
  
          // Send the index page
          if ("/".equals(req.getUri()) || "/1.jsp".equals(req.getUri())) {
              String webSocketLocation = getWebSocketLocation(ctx.pipeline(), req, websocketPath);
              //http://netty.io/4.0/xref/io/netty/example/http/websocketx/server/WebSocketServerIndexPage.html
              ByteBuf content =Unpooled.copiedBuffer("test", CharsetUtil.US_ASCII);// WebSocketServerIndexPage.getContent(webSocketLocation);
              FullHttpResponse res = new DefaultFullHttpResponse(HTTP_1_1, OK, content);
  
              res.headers().set(HttpHeaders.Names.CONTENT_TYPE, "text/html; charset=UTF-8");
              HttpHeaders.setContentLength(res, content.readableBytes());
  
              sendHttpResponse(ctx, req, res);
          } else {
              sendHttpResponse(ctx, req, new DefaultFullHttpResponse(HTTP_1_1, NOT_FOUND));
          }
      }
  
      @Override
      public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
          cause.printStackTrace();
          ctx.close();
      }
  
      private static void sendHttpResponse(ChannelHandlerContext ctx, FullHttpRequest req, FullHttpResponse res) {
          // Generate an error page if response getStatus code is not OK (200).
          if (res.getStatus().code() != 200) {
              ByteBuf buf = Unpooled.copiedBuffer(res.getStatus().toString(), CharsetUtil.UTF_8);
              res.content().writeBytes(buf);
              buf.release();
              HttpHeaders.setContentLength(res, res.content().readableBytes());
          }
  
          // Send the response and close the connection if necessary.
          ChannelFuture f = ctx.channel().writeAndFlush(res);
          if (!HttpHeaders.isKeepAlive(req) || res.getStatus().code() != 200) {
              f.addListener(ChannelFutureListener.CLOSE);
          }
     }
 
     private static String getWebSocketLocation(ChannelPipeline cp, HttpRequest req, String path) {
         String protocol = "ws";
         if (cp.get(SslHandler.class) != null) {
             // SSL in use so use Secure WebSockets
             protocol = "wss";
         }
        return protocol + "://" + req.headers().get(HttpHeaders.Names.HOST) + path;
     }
 }
